#include <bits/stdc++.h>
using namespace std;

char ans[101];
int cnt1[26], cnt2[26], f[101][26];
#pragma GCC optimize(3)

struct cmp {
    bool operator()(const string& a, const string& b) const
    {
        if (a.size() != b.size())
            return a.size() < b.size();
        return a < b;
    }
};

void solve(int x)
{
    cout << "? 1 " << x << endl;
    cout.flush();
    multiset<string, cmp> s;
    string input;
    for (int i = 1; i <= x * (x + 1) / 2; i++) {
        cin >> input;
        sort(input.begin(), input.end());
        s.insert(input);
    }
    cout << "? 1 " << x - 1 << endl;
    cout.flush();
    for (int i = 1; i <= x * (x - 1) / 2; i++) {
        cin >> input;
        sort(input.begin(), input.end());
        s.erase(s.find(input));
    }
    int now = x;
    for (string str : s) {
        memset(cnt2, 0, sizeof cnt2);
        for (int i = 0; i < str.size(); i++)
            cnt2[str[i] - 'a']++;
        for (int i = 0; i < str.size(); i++)
            if (cnt2[str[i] - 'a'] > cnt1[str[i] - 'a'])
                ans[now--] = str[i], cnt1[str[i] - 'a'] = cnt2[str[i] - 'a'];
    }
}

void solve2(int x)
{
    cout << "? 1 " << x << endl;
    cout.flush();
    string input;
    for (int i = 1; i <= x * (x + 1) / 2; i++) {
        cin >> input;
        for (int j = 0; j < input.size(); j++)
            f[input.size()][input[j] - 'a']++;
    }
    for (int i = (x - 1) / 2; i >= 0; i--) {
        int l = i + 1, r = x - i;
        memset(cnt1, 0, sizeof cnt1);
        for (int j = l; j <= r; j++)
            cnt1[ans[j] - 'a']++;
        for (int j = 0; j < 26; j++)
            if (f[i + 1][j] - f[i][j] > cnt1[j])
                ans[r] = 'a' + j;
    }
}

int main()
{
    int n;
    cin >> n;
    if (n <= 3) {
        for (int i = 1; i <= n; i++) {
            cout << "? " << i << " " << i << endl;
            cout.flush();
            cin >> ans[i];
        }
    } else
        solve(n / 2), solve2(n);
    cout << "! ";
    for (int i = 1; i <= n; i++)
        cout << ans[i];
    return 0;
}
